package App.Filter;

import App.Model.ApiLogMessage;
import com.alibaba.fastjson.JSON;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
import org.springframework.web.util.WebUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;


import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.output.TeeOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * Created by xw on 2018/11/19.
 */
public class LoggableDispatcherServlet extends DispatcherServlet {

    private final Log _log = LogFactory.getLog(getClass());

    @Override
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        if (!(request instanceof ContentCachingRequestWrapper)) {
            request = new ContentCachingRequestWrapper(request);
        }
        if (!(response instanceof ContentCachingResponseWrapper)) {
            response = new ContentCachingResponseWrapper(response);
        }
        HandlerExecutionChain handler = getHandler(request);

        try {
            super.doDispatch(request, response);
        } finally {
            log(request, response, handler);
            updateResponse(response);
        }
    }

    private void log(HttpServletRequest _request, HttpServletResponse _response, HandlerExecutionChain handler) {



        /*
        _log.info();
        LogMessage log = new LogMessage();
        log.setHttpStatus(responseToCache.getStatus());
        log.setHttpMethod(requestToCache.getMethod());
        log.setPath(requestToCache.getRequestURI());
        log.setClientIp(requestToCache.getRemoteAddr());
        log.setJavaMethod(handler.toString());
        log.setResponse(getResponsePayload(responseToCache));
        logger.info(log);
        */

//        RequestCache.

        //  SecurityContext.
        ApiLogMessage _logMessage = new ApiLogMessage();

        StringBuilder _strBuilder = new StringBuilder();
        _strBuilder.append("Url:"+_request.getRequestURL());
        _strBuilder.append("Request Method:" + _request.getMethod() + System.lineSeparator());
        _strBuilder.append("Request Headers:" + System.lineSeparator());

        //header
        Enumeration<String> _headers = _request.getHeaderNames();
        while (_headers.hasMoreElements()) {
            String _headerName = _headers.nextElement();
            String _headerValue = _request.getHeader(_headerName);
            _strBuilder.append(_headerName + ":" + _headerValue + System.lineSeparator());
        }

        String _contentType = _request.getContentType();
        _strBuilder.append("请求参数：" + _contentType + System.lineSeparator());

        String content = "";

        //_request.getPart()
      //  _request.getPart("")



        try {

            // if ("POST".equalsIgnoreCase(_request.getMethod())) {
            content = _request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
            //content=IOUtils.toString(_request.getReader());
            // }
        } catch (Exception ex) {
            ex.printStackTrace();
        }


        String requsetStr = _strBuilder.toString();
        _log.info("--requst log----");
        _log.info(requsetStr);


        _log.info("--response log----");
        _logMessage.setHttpStatus(_response.getStatus());
        String _responseStr = getResponsePayload(_response);
        _log.info(_responseStr);

    }

    private String getResponsePayload(HttpServletResponse response) {
        ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
        if (wrapper != null) {

            byte[] buf = wrapper.getContentAsByteArray();
            if (buf.length > 0) {
                int length = Math.min(buf.length, 5120);
                try {
                    return new String(buf, 0, length, wrapper.getCharacterEncoding());
                } catch (UnsupportedEncodingException ex) {
                    // NOOP
                }
            }
        }
        return "[unknown]";
    }

    private void updateResponse(HttpServletResponse response) throws IOException {
        ContentCachingResponseWrapper
                responseWrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
        responseWrapper.copyBodyToResponse();
    }



}